﻿namespace Okazuki.MVVM.PrismSupport.Test.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using Microsoft.Practices.Prism.Commands;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Okazuki.MVVM.PrismSupport.Utils;
    using Okazuki.MVVM.PrismSupport.ViewModels;

    [TestClass]
    public class ViewModelBaseAutoCommandTest
    {
        class MockViewModel : ViewModelBase
        {
            #region AlertCommand
            public bool AlertExecuted { get; set; }

            public bool CanAlertExecuted { get; set; }

            [AutoInitCommand]
            public DelegateCommand AlertCommand { get; private set; }

            [CommandMethod]
            private void AlertExecute()
            {
                this.AlertExecuted = true;
            }

            [CommandMethod]
            private bool CanAlertExecute()
            {
                this.CanAlertExecuted = true;
                return true;
            }
            #endregion

            #region ParamCommand
            [AutoInitCommand]
            public DelegateCommand<string> ParamCommand { get; private set; }

            public string ParamExecuteParameter { get; set; }
            [CommandMethod]
            private void ParamExecute(string parameter)
            {
                this.ParamExecuteParameter = parameter;
            }

            public string CanParamExecuteParameter { get; set; }
            [CommandMethod]
            private bool CanParamExecute(string parameter)
            {
                this.CanParamExecuteParameter = parameter;
                return !string.IsNullOrWhiteSpace(parameter);
            }
            #endregion
            
            #region ParamNoCanExecuteCommand
            [AutoInitCommand]
            public DelegateCommand<string> Param2Command { get; private set; }

            public string Param2CommandParameter { get; set; }
            [CommandMethod]
            private void Param2Execute(string parameter)
            {
                this.Param2CommandParameter = parameter;
            }
            #endregion
        }

        private MockViewModel target;

        [TestInitialize]
        public void SetUp()
        {
            this.target = new MockViewModel();
        }

        [TestCleanup]
        public void TearDown()
        {
            this.target = null;
        }

        [TestMethod]
        public void TestNonParameterCommandProperty()
        {
            Assert.IsNotNull(this.target.AlertCommand);
            Assert.IsTrue(this.target.AlertCommand.CanExecute());
            Assert.IsTrue(this.target.CanAlertExecuted);

            this.target.AlertCommand.Execute();
            Assert.IsTrue(this.target.AlertExecuted);
        }

        [TestMethod]
        public void TestParameterCommandProperty()
        {
            Assert.IsNotNull(this.target.ParamCommand);
            Assert.IsTrue(this.target.ParamCommand.CanExecute("arg"));
            Assert.AreEqual("arg", this.target.CanParamExecuteParameter);

            this.target.ParamCommand.Execute("arg");
            Assert.AreEqual("arg", this.target.ParamExecuteParameter);
        }

        [TestMethod]
        public void TestParameterCommandProperty2()
        {
            Assert.IsNotNull(this.target.Param2Command);
            Assert.IsTrue(this.target.Param2Command.CanExecute("arg"));

            this.target.Param2Command.Execute("arg");
            Assert.AreEqual("arg", this.target.Param2CommandParameter);
        }
    }
}
